﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Dominio;
using System.Data.Objects;

namespace Persistencia
{
    public class AtletaEquipoPersistencia
    {
        public void InsertarAtletaEquipo(Participante participante)
        {
            using (OlimpycsLondonEntities entities = new OlimpycsLondonEntities())
            {
                PARTICIPANTE participanteDB = GetParticipanteEntity(participante);
                entities.PARTICIPANTE.AddObject(participanteDB);

                foreach (Deporte deporte in participante.Deportes)
                {
                    PARTICIPANTE_DEPORTE participante_deporte = new PARTICIPANTE_DEPORTE();
                    participante_deporte.PARTICIPANTE = participanteDB.ID;
                    participante_deporte.DEPORTE = deporte.Id;
                    entities.PARTICIPANTE_DEPORTE.AddObject(participante_deporte);
                }

                foreach (string comentario in participante.Comentarios)
                {
                    PARTICIPANTE_COMENTARIO participante_comentario = new PARTICIPANTE_COMENTARIO();
                    participante_comentario.PARTICIPANTE = participanteDB.ID;
                    participante_comentario.COMENTARIO = comentario;
                    participante_comentario.FECHA = DateTime.Now;
                    entities.PARTICIPANTE_COMENTARIO.AddObject(participante_comentario);
                }

                entities.SaveChanges();
            }
        }

        public void ModificarAtletaEquipoDeportes(Participante participante)
        {
            EliminarTodosDeportesAtletaEquipo(participante);

            using (OlimpycsLondonEntities entities = new OlimpycsLondonEntities())
            {
                foreach (Deporte deporte in participante.Deportes)
                {
                    PARTICIPANTE_DEPORTE participante_deporte = new PARTICIPANTE_DEPORTE();
                    participante_deporte.PARTICIPANTE = participante.Id;
                    participante_deporte.DEPORTE = deporte.Id;
                    entities.PARTICIPANTE_DEPORTE.AddObject(participante_deporte);
                }

                entities.SaveChanges();
            }
        }

        public void ModificarAtletaEquipoPrincipal(Participante participante)
        {
            using (OlimpycsLondonEntities entities = new OlimpycsLondonEntities())
            {
                PARTICIPANTE participanteEntity = entities.PARTICIPANTE.FirstOrDefault(p => p.ID == participante.Id);
                if (participante.Foto != null)
                {
                    participanteEntity.FOTO = participante.Foto;
                }
                participanteEntity.NOMBRE = participante.Nombre;
                participanteEntity.PAIS = participante.Pais.Id;

                if (participante.TipoParticipante.Equals(Participante.Tipo.Atleta.ToString()))
                {
                    participanteEntity.TIPO = (int)Participante.Tipo.Atleta;
                }
                else
                {
                    participanteEntity.TIPO = (int)Participante.Tipo.Equipo;
                }

                entities.SaveChanges();
            }
        }

        public void AgregarAtletaEquipoComentario(int participanteId, string comentario)
        {
            using (OlimpycsLondonEntities entities = new OlimpycsLondonEntities())
            {
                PARTICIPANTE_COMENTARIO participante_comentario = new PARTICIPANTE_COMENTARIO();
                participante_comentario.PARTICIPANTE = participanteId;
                participante_comentario.COMENTARIO = comentario;
                participante_comentario.FECHA = DateTime.Now;
                entities.PARTICIPANTE_COMENTARIO.AddObject(participante_comentario);

                entities.SaveChanges();
            }
        }

        public void EliminarAtletaEquipoComentario(int participanteComentarioId)
        {
            using (OlimpycsLondonEntities entities = new OlimpycsLondonEntities())
            {
                PARTICIPANTE_COMENTARIO participante_comentario = entities.PARTICIPANTE_COMENTARIO.FirstOrDefault(pc => pc.ID == participanteComentarioId);
                entities.PARTICIPANTE_COMENTARIO.DeleteObject(participante_comentario);

                entities.SaveChanges();
            }
        }

        public void EliminarAtletaEquipo(Participante participante)
        {
            EliminarTodosDeportesAtletaEquipo(participante);
            EliminarTodosComentariosAtletaEquipo(participante);

            using (OlimpycsLondonEntities entities = new OlimpycsLondonEntities())
            {
                PARTICIPANTE participanteDB = entities.PARTICIPANTE.Include("PARTICIPANTE_DEPORTE").FirstOrDefault(p => p.ID == participante.Id);

                entities.PARTICIPANTE.DeleteObject(participanteDB);

                entities.SaveChanges();
            }
        }

        private void EliminarTodosDeportesAtletaEquipo(Participante participante)
        {
            using (OlimpycsLondonEntities entities = new OlimpycsLondonEntities())
            {
                List<PARTICIPANTE_DEPORTE> deportesParticipantes = ((from p in entities.PARTICIPANTE
                                                                     join pd in entities.PARTICIPANTE_DEPORTE on p.ID equals pd.PARTICIPANTE
                                                                     where p.ID == participante.Id
                                                                     select pd) as ObjectQuery<PARTICIPANTE_DEPORTE>).ToList();

                foreach (PARTICIPANTE_DEPORTE participanteDeporteBD in deportesParticipantes)
                {
                    entities.PARTICIPANTE_DEPORTE.DeleteObject(participanteDeporteBD);
                }

                entities.SaveChanges();
            }
        }

        private void EliminarTodosComentariosAtletaEquipo(Participante participante)
        {
            using (OlimpycsLondonEntities entities = new OlimpycsLondonEntities())
            {
                List<PARTICIPANTE_COMENTARIO> comentariosParticipantes = ((from p in entities.PARTICIPANTE
                                                                           join pc in entities.PARTICIPANTE_COMENTARIO on p.ID equals pc.PARTICIPANTE
                                                                           where p.ID == participante.Id
                                                                           select pc) as ObjectQuery<PARTICIPANTE_COMENTARIO>).ToList();

                foreach (PARTICIPANTE_COMENTARIO comentarioParticipanteBD in comentariosParticipantes)
                {
                    entities.PARTICIPANTE_COMENTARIO.DeleteObject(comentarioParticipanteBD);
                }

                entities.SaveChanges();
            }
        }


        public List<Participante> GetAllAtletaEquipo()
        {
            List<Participante> participantes = new List<Participante>();

            using (OlimpycsLondonEntities entities = new OlimpycsLondonEntities())
            {
                List<PARTICIPANTE> participantesDB = entities.PARTICIPANTE.Include("PARTICIPANTE_DEPORTE").ToList();
                Participante participante = null;
                foreach (PARTICIPANTE participanteDB in participantesDB)
                {
                    participante = GetParticipanteDomain(participanteDB);
                    participantes.Add(participante);
                }
            }

            return participantes;
        }

        public Participante GetAtletaEquipo(string nombre)
        {
            Participante participante = null;

            using (OlimpycsLondonEntities entities = new OlimpycsLondonEntities())
            {
                PARTICIPANTE participanteBD = entities.PARTICIPANTE.Include("PARTICIPANTE_DEPORTE").FirstOrDefault(p => p.NOMBRE == nombre);
                if (participanteBD != null)
                {
                    participante = GetParticipanteDomain(participanteBD);
                }
            }

            return participante;
        }

        public Participante GetAtletaEquipo(int id)
        {
            Participante participante = null;

            using (OlimpycsLondonEntities entities = new OlimpycsLondonEntities())
            {
                PARTICIPANTE participanteBD = entities.PARTICIPANTE.Include("PARTICIPANTE_DEPORTE").FirstOrDefault(p => p.ID == id);
                if (participanteBD != null)
                {
                    participante = GetParticipanteDomain(participanteBD);
                }
            }

            return participante;
        }

        public List<Participante> GetAtletaEquipoSeguidos(string username)
        {
            List<Participante> participantes = new List<Participante>();

            using (OlimpycsLondonEntities entities = new OlimpycsLondonEntities())
            {
                List<PARTICIPANTE> participantesBD = ((from u in entities.USUARIO
                                                       join ups in entities.USUARIO_PARTICIPANTE_SEGUIDO on u.ID equals ups.USUARIO
                                                       join p in entities.PARTICIPANTE on ups.PARTICIPANTE equals p.ID
                                                       where u.USERNAME == username
                                                       select p) as ObjectQuery<PARTICIPANTE>).ToList();

                Participante participante = null;
                foreach (PARTICIPANTE participanteBd in participantesBD)
                {
                    participante = GetParticipanteDomain(participanteBd);
                    participantes.Add(participante);
                }
            }

            return participantes;
        }

        public List<Participante> GetAtletasEquipsoByDeporte(int deporteId)
        {
            List<Participante> participantes = new List<Participante>();

            using (OlimpycsLondonEntities entities = new OlimpycsLondonEntities())
            {
                List<PARTICIPANTE> participantesBD = ((from p in entities.PARTICIPANTE
                                                       join pd in entities.PARTICIPANTE_DEPORTE on p.ID equals pd.PARTICIPANTE
                                                       join d in entities.DEPORTE on pd.DEPORTE equals d.ID
                                                       where d.ID == deporteId
                                                       select p) as ObjectQuery<PARTICIPANTE>).ToList();

                Participante participante = null;
                foreach (PARTICIPANTE participanteBd in participantesBD)
                {
                    participante = GetParticipanteDomain(participanteBd);
                    participantes.Add(participante);
                }
            }

            return participantes;
        }

        public void ActualizarAtletaEquipoSeguidos(int userId, int[] atletasEquiposSeguidosIds)
        {
            EliminarTodosAtletasEquiposSeguidos(userId);

            using (OlimpycsLondonEntities entities = new OlimpycsLondonEntities())
            {
                for (int i = 0; i < atletasEquiposSeguidosIds.Length; i++)
                {
                    USUARIO_PARTICIPANTE_SEGUIDO usuario_participante_seguido = new USUARIO_PARTICIPANTE_SEGUIDO();
                    usuario_participante_seguido.USUARIO = userId;
                    usuario_participante_seguido.PARTICIPANTE = atletasEquiposSeguidosIds[i];
                    entities.USUARIO_PARTICIPANTE_SEGUIDO.AddObject(usuario_participante_seguido);
                }

                entities.SaveChanges();
            }
        }


        public bool existeAtletaSeguidoPorUsuario(int usrId, int partId)
        {
            try
            {
                using (OlimpycsLondonEntities entities = new OlimpycsLondonEntities())
                {
                    USUARIO_PARTICIPANTE_SEGUIDO upsDB = entities.USUARIO_PARTICIPANTE_SEGUIDO.FirstOrDefault((p => p.USUARIO == usrId && p.PARTICIPANTE == partId));
                    return upsDB != null;
                }
            }
            catch (Exception ex)
            { throw ex; }
        }

        public void AgregarAtletaEquipoSeguidos(int userId, List<int> atletasEquiposSeguidosIds)
        {
            try
            {

                using (OlimpycsLondonEntities entities = new OlimpycsLondonEntities())
                {
                    foreach (int idPart in atletasEquiposSeguidosIds)
                    {
                        if (!existeAtletaSeguidoPorUsuario(userId, idPart))
                        {

                            USUARIO_PARTICIPANTE_SEGUIDO usuario_participante_seguido = new USUARIO_PARTICIPANTE_SEGUIDO();
                            usuario_participante_seguido.USUARIO = userId;
                            usuario_participante_seguido.PARTICIPANTE = idPart;
                            entities.USUARIO_PARTICIPANTE_SEGUIDO.AddObject(usuario_participante_seguido);
                        }
                    }
                    entities.SaveChanges();
                }
            }
            catch (Exception ex) { throw ex; }
        }


        private void EliminarTodosAtletasEquiposSeguidos(int userId)
        {
            using (OlimpycsLondonEntities entities = new OlimpycsLondonEntities())
            {
                List<USUARIO_PARTICIPANTE_SEGUIDO> participantesSeguidosDB = ((from ups in entities.USUARIO_PARTICIPANTE_SEGUIDO
                                                                               where ups.USUARIO == userId
                                                                               select ups) as ObjectQuery<USUARIO_PARTICIPANTE_SEGUIDO>).ToList();

                foreach (USUARIO_PARTICIPANTE_SEGUIDO participanteSeguidosDB in participantesSeguidosDB)
                {
                    entities.USUARIO_PARTICIPANTE_SEGUIDO.DeleteObject(participanteSeguidosDB);
                }

                entities.SaveChanges();
            }
        }

        public List<Pais> GetPaises()
        {
            List<Pais> paises = new List<Pais>();

            using (OlimpycsLondonEntities entities = new OlimpycsLondonEntities())
            {
                List<PAIS> paisesDB = entities.PAIS.ToList();
                Pais pais = null;
                foreach (PAIS paisDB in paisesDB)
                {
                    pais = new Pais();
                    pais.Id = paisDB.ID;
                    pais.Nombre = paisDB.NOMBRE;

                    paises.Add(pais);
                }
            }

            return paises;
        }

        internal static Participante GetParticipanteDomain(PARTICIPANTE participanteEntity)
        {
            Participante participante = null;
            if (participanteEntity.TIPO == (int)Participante.Tipo.Atleta)
                participante = new Atleta();
            else
                participante = new Equipo();

            participante.Id = participanteEntity.ID;
            participante.Nombre = participanteEntity.NOMBRE;
            participante.Foto = participanteEntity.FOTO;

            if (participanteEntity.PAIS1 != null)
            {
                Pais pais = new Pais();
                pais.Id = participanteEntity.PAIS1.ID;
                pais.Nombre = participanteEntity.PAIS1.NOMBRE;
                participante.Pais = pais;
            }

            foreach (PARTICIPANTE_DEPORTE deporteEntity in participanteEntity.PARTICIPANTE_DEPORTE)
            {
                Deporte deporte = DeportePersistencia.GetDeporteDomain(deporteEntity.DEPORTE1);
                participante.Deportes.Add(deporte);
            }

            foreach (PARTICIPANTE_COMENTARIO comentarioEntity in participanteEntity.PARTICIPANTE_COMENTARIO)
            {
                if (comentarioEntity.FECHA != null)
                {
                    participante.Comentarios.Add(comentarioEntity.FECHA.ToString() + " - " + comentarioEntity.COMENTARIO);
                }
                else participante.Comentarios.Add(comentarioEntity.COMENTARIO);
            }

            return participante;
        }

        internal static PARTICIPANTE GetParticipanteEntity(Participante participante)
        {
            PARTICIPANTE participanteEntity = new PARTICIPANTE();
            participanteEntity.FOTO = participante.Foto;
            participanteEntity.NOMBRE = participante.Nombre;
            participanteEntity.PAIS = participante.Pais.Id;

            if (participante.TipoParticipante.Equals(Participante.Tipo.Atleta.ToString()))
            {
                participanteEntity.TIPO = (int)Participante.Tipo.Atleta;
            }
            else
            {
                participanteEntity.TIPO = (int)Participante.Tipo.Equipo;
            }

            return participanteEntity;
        }
    }
}
